package com.xb.loan.util;


import com.xb.loan.util.log.DefaultLoggerFacotry;
import org.slf4j.Logger;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 对象处理工具类，提供创建、填充对象的基本方法。 使用反射对类成员的访问
 *
 */
public class ObjectHelper {

	private static Logger logger = DefaultLoggerFacotry.getLogger(ObjectHelper.class);

	@SuppressWarnings("unchecked")
	private static Map<String, Class> ClassStorage = new HashMap<String, Class>();

	private static List<String> ENTOSTRING_CLASSNAMES = new ArrayList<String>();

	// 将能够直接进行字符串转化的类型放入到list中，以便判断该类型是否可以直接调用
	// ValueOf方法对其进行字符串
	static {
		ENTOSTRING_CLASSNAMES.add("int");
		ENTOSTRING_CLASSNAMES.add("long");
		ENTOSTRING_CLASSNAMES.add("double");
		ENTOSTRING_CLASSNAMES.add("byte");
		ENTOSTRING_CLASSNAMES.add("float");
		ENTOSTRING_CLASSNAMES.add(Long.class.getName());
		ENTOSTRING_CLASSNAMES.add(Double.class.getName());
		ENTOSTRING_CLASSNAMES.add(java.util.Date.class.getName());
		ENTOSTRING_CLASSNAMES.add(Integer.class.getName());
		ENTOSTRING_CLASSNAMES.add(Float.class.getName());

		ENTOSTRING_CLASSNAMES.add(String.class.getName());
	}

	/**
	 * ClassForName方法的封装，
	 * 
	 * @param className
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Class getClass(String className) {
		Class c = ClassStorage.get(className);

		if (c == null) {
			try {
				c = Class.forName(className);
				ClassStorage.put(className, c);
				logger.debug("Add class to storage,");
			} catch (Exception e) {
				logger.error(className + " not found!");
			}
		}
		return c;
	}

	/**
	 * 实例对象，简单化实例对象，
	 * 
	 * @param className
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Object simpleNewInstance(String className) {
		Object o = null;
		Class c = getClass(className);
		if (c != null) {
			logger.debug("find class " + className);

			try {
				o = c.newInstance();
			} catch (InstantiationException e) {
				logger.error("实例化" + className + "失败" + e.getMessage());
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				logger.error("实例化" + className + "失败" + e.getMessage());
				e.printStackTrace();
			}

		}
		return o;
	}

	/**
	 * 为对象添加成员变量的值
	 * 
	 * @param owner
	 * @param value
	 * @param filedName
	 * @return
	 * @throws Exception
	 * @throws Exception
	 */
	public static Object setFiledValue(Object owner, Object value, String filedName) {

		if (owner != null) {
			@SuppressWarnings("unused")
			Field field;
			try {
				// field = owner.getClass().getField(filedName);
				// field.set(owner, value);
				String methodname = "set" + filedName.substring(0, 1).toUpperCase()
						+ filedName.substring(1);
				Object[] params = new Object[1];
				params[0] = value;
				invokeMethod(owner, methodname, params);
			} catch (Exception e) {
				logger.error("setFiledValue:" + filedName + "=" + value + e.getMessage());
				return null;
			}
		}

		return owner;

	}

	/**
	 * 调用某个对象的方法
	 * 
	 * @param owner
	 * @param methodName
	 * @param args
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Object invokeMethod(Object owner, String methodName, Object[] args)
			throws Exception {
		if (owner != null) {
			// 创建参数类型列表。
			Class[] parmsClasses = null;
			if (args == null)
				parmsClasses = new Class[0];
			else {
				parmsClasses = new Class[args.length];
				for (int i = 0; i < args.length; i++) {
					Object parm = args[i];
					if (parm != null) {
						parmsClasses[i] = parm.getClass();
					}
				}
			}

			// 获取方法对象

			Method method = owner.getClass().getMethod(methodName, parmsClasses);

			return method.invoke(owner, args);
		}
		return null;
	}

	/**
	 * 调用静态方法
	 * 
	 * @param className
	 * @param methodName
	 * @param args
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Object invokeStaticMehtod(String className, String methodName, Object[] args)
			throws Exception {
		Class c = getClass(className);
		if (c != null) {
			Class[] parmsClasses = null;
			if (args == null)
				parmsClasses = new Class[0];
			else {
				parmsClasses = new Class[args.length];
				for (int i = 0; i < args.length; i++) {
					Object parm = args[i];
					if (parm != null) {
						parmsClasses[i] = parm.getClass();
					}
				}
			}

			Method method = c.getMethod(methodName, parmsClasses);

			return method.invoke(null, args);

		}
		return null;
	}

	public static Field getField(Object owner, String fieldName) throws Exception {
		return owner.getClass().getDeclaredField(fieldName);
	}

	public static Field[] getFiled(Object owner) {
		Field[] fields = owner.getClass().getDeclaredFields();
		return fields;
	}

	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception {
		List<String> list = new ArrayList<String>(0);
		Method method = list.getClass().getMethod("get", int.class);

		@SuppressWarnings("unused")
		Class c = method.getReturnType();
		System.out.println(Double.class.getName());
	}

	public static boolean canValueOf(Field field) {
		boolean result = false;
		result = ENTOSTRING_CLASSNAMES.contains(field.getType().getName());
		return result;
	}
}
